package com.tree.thread;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 *
 *类说明：抛出InterruptedException异常的时候，要注意中断标志位
 */
public class ThreadInterruptExample {
	
	private static SimpleDateFormat formater 
		= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss_SSS");

    public static void main(String[] args) throws InterruptedException {

        //callFirstInterruptThread();
//        callTwiceInterruptThread();
        callClearStatusThreadByInterrupted();

    }



    private static void callFirstInterruptThread() throws InterruptedException {
        Thread endThread = new FirstInterruptStopThread("FirstInterruptStopThread");
        endThread.start();
        Thread.sleep(10);
        System.out.println("主线程【"+Thread.currentThread().getName()+"】 休息完100s， 开始中断， 时间:"+formater.format(new Date()));
        endThread.interrupt();

    }

    private static void callTwiceInterruptThread() throws InterruptedException {
        Thread endThread = new TwiceInterruptStopThread("TwiceInterruptStopThread");
        endThread.start();
        System.out.println("Main:"+formater.format(new Date()));
        Thread.sleep(100);
        System.out.println("主线程【"+Thread.currentThread().getName()+"】 休息完100s， 开始中断， 时间:"+formater.format(new Date()));
        endThread.interrupt();

    }

    //使用Thread.interrupted();
    private static void callClearStatusThreadByInterrupted() {

        System.out.println("开始第一次中断， 状态为："+Thread.interrupted());
        System.out.println("获取状态："+Thread.currentThread().isInterrupted());
        Thread.currentThread().interrupt();
        System.out.println("开始第一次中断， 状态为："+Thread.interrupted());
        System.out.println("获取状态："+Thread.currentThread().isInterrupted());
        System.out.println(Thread.currentThread().isInterrupted());

    }

    /**
     * 在使用interrupt方法时， 中断1次， 线程的中断状态为true， 不会被清楚
     */
    private static class FirstInterruptStopThread extends Thread{
        public FirstInterruptStopThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            String threadName = Thread.currentThread().getName();
            while(!isInterrupted()) {
                try {
                    System.out.println("当前线程【"+threadName+"】状态为"+isInterrupted()+"， 时间: "+formater.format(new Date()));
                } catch (Exception e) {
                    System.err.println("线程【"+threadName+"】 异常， 当前中断标识 interrupt flag is " +isInterrupted()+ " ， 时间："  +(formater.format(new Date())));
                    e.printStackTrace();
                }
            }
            System.out.println("结束当前线程【"+threadName+"】状态为"+isInterrupted());

        }
    }



    /**
     * 在使用interrupt方法时， 如果遇到线程正在休眠sleep或者阻塞状态wait\join时， 会报异常，
     * 同时清楚线程中断状态， 即为false
     *
     * 通常咱们可以设置一个公共变量， 死循环中while循环公共变量， 当遇到了异常， 我们可以设置公共变量为true， 然后就能跳出死循环或者直接再中断一次
     */
	private static class TwiceInterruptStopThread extends Thread{
		
		public TwiceInterruptStopThread(String name) {
			super(name);
		}
		
		@Override
		public void run() {
			String threadName = Thread.currentThread().getName();
			while(!isInterrupted()) {
				try {
                    System.out.println("当前线程【"+threadName+"】状态为"+isInterrupted()+"， 时间: "+formater.format(new Date()));
					Thread.sleep(3000);
				} catch (Exception e) {
                    System.err.println("线程【"+threadName+"】 异常， 当前中断标识 【" +isInterrupted()+ "】, 第二次开始调用interrupt方法 ， 时间："  +(formater.format(new Date())));
					interrupt();
                    System.err.println("线程【"+threadName+"】 第二次调用interrupt方法之后获取中断标识 【 " +isInterrupted()+ "】 ， 时间："  +(formater.format(new Date())));
                    e.printStackTrace();
				}
			}
            System.out.println("结束当前线程【"+threadName+"】状态为"+isInterrupted());

		}
	}





}
